/*RFW.bobstyle = 1

RFW.Weapons = { //DO NOT MANUALLY ADD WEAPONS TO THIS TABLE, I WILL FIND YOU AND I WILL KILL YOU IF YOU DO
	[1] = {}, //slot 1, normal slot
	[2] = {}, //slot 2, automatic slot
	[3] = {}, //slot 3, bounce slot
	[4] = {}, //slot 4, scatter slot
	[5] = {}, //slot 5, grenade slot
	[6] = {}, //slot 6, explosion slot
	[7] = {}, //slot 7, rail slot
	[8] = {}, //slot 8, galactic earth shaker megakill death laser slot
	[9] = {}, //slot 9, giga death superkill planet cra- wait wait wait, slot 8 and slot 9???
	//what the fuck, theres only 7 weapon slots in srb2, rdude you FUCKING DUMB CUN-
	//well ACTUALLY, there ARE 10 weapon keys in srb2, as evident by game control constants "GC_WEPSLOT8", "GC_WEPSLOT9" and "GC_WEPSLOT10"
	//HOWEVER, they aren't bindable in the controls menu, I BELIEVE they are bound by default to 8, 9, and 0 respectively
	//but if they for some reason arent you can always also bind them using "setcontrol weapon[8/9/10] [keyname]"
	[10] = {}, //slot 10 or 0, whatever you wanna call it, insert joke about what slot this is in srb2
} //DO NOT MANUALLY ADD WEAPONS TO THIS TABLE, I WILL FIND YOU AND I WILL KILL YOU IF YOU DO

RFW.Ammoids = {
[1] = {"Bullets", 400},
[2] = {"Shells", 100},
[3] = {"Rockets", 100},
[4] = {"Cells", 600},
}

function RFW.AddWeapon(slot, data)
	local constant = 1 + #RFW.Weapons[slot]
	RFW.Weapons[slot][constant] = data
	return constant
end

function RFW.WeaponValid(p)
	if p.spectator then return false end
	if p.playerstate == PST_DEAD then return false end
	if p.slot == nil then return false end
	if p.weapon == nil then return false end
	if p.weaponframe == nil then return false end
	return true
end

function RFW.PlayerHasWeapon(p, slot, weapon)
	local has = false
	for k, v in ipairs(p.weaponslist[slot]) do //iterate through our current slot
		if v == weapon then //if the current key value is our current gun
			has = true
			break
		end
	end
	return has
end

function RFW.GivePlayerWeapon(p, slot, weapon)
	if RFW.PlayerHasWeapon(p, slot, weapon) == true then
		return false //dont give the player a weapon they already have, i havent tested it but seeing as the inventory is just a table of weapon ids that the player owns in order if we didn't do this than most likely we would have duplicate weapons
	end //that being said it would maybe be useful to remove this part than if you're doing a hideous destructor style system. Or not probably, it'd probably just be easier to have one weapon pick up and then have a table for each weapon that has the info for each copy of the weapon. just spit balling here. totally.
	local constant = 1 + #p.weaponslist[slot]
	p.weaponslist[slot][constant] = weapon
	table.sort(p.weaponslist[slot], function(a, b)
		//local ap = (RFW.Weapons[p.slot][a]["Priority"] and RFW.Weapons[p.slot][a]["Priority"]) or 1000
		//local bp =
		return (RFW.Weapons[slot][a]["Priority"] or (1000+a)) < (RFW.Weapons[slot][b]["Priority"] or (1000+b))
	end)
	return true
end

function RFW.NextWeapon(p, switch) //start switching to next weapon
	if switch == nil then
		switch = true
	end
	local dick = 0
	local dick2 = 0
	if p.switchto == nil or p.switchslot == nil then
		dick = p.weapon //store the weapon id
		dick2 = p.slot //and the slot, this saves performance and allows me to not have to write everything twice
	else //and thats because if we're already attempting to switch weapons
		dick = p.switchto //then we store the id of the weapon we're switching to!
		dick2 = p.switchslot //same with slot
	end
	local nextweapon = 0
	local weapon = 0
	local slot = dick2
	for k, v in ipairs(p.weaponslist[dick2]) do //iterate through our current slot
		if nextweapon == 1 then //if our next gun is the one we want then cache the weapon id
			weapon = v
			break
		end
		if v == dick then //if the current key value is our current gun
			nextweapon = 1
			continue
		end
	end
	if nextweapon == 1 and weapon == 0 then //if we need to find the next gun but we're out of guns in our current slot then iterate through the next slots
		for die = 1, 9 do //iterate through the next 9 slots
			local FUCK = dick2 + die //next slot is our slot + 1
			if FUCK > 10 then //if we go over 10 than wrap back around
				FUCK = dick2 + die - 10
			end
			if #p.weaponslist[FUCK] ~= 0 then //if theres anything in this new slots table then logically it will always be the 
				weapon = p.weaponslist[FUCK][1]
				slot = FUCK
				break
			else
				continue
			end
		end
	end
	if nextweapon == 1 and weapon == 0 then //we STILL don't have a weapon! benson is gonna be so pissed bro.
		if #p.weaponslist[dick2] ~= 1 then //if we have more than one weapon in the slot
			weapon = p.weaponslist[dick2][1] //will always be the first weapon then, if we started from the first weapon of a slot and the length was more than 1 then we would have been done back at the first check
			slot = dick2 //it should still be dick2 anyways but we're just making sure
		else
			switch = false //we shouldn't try to switch to our same weapon again, never switch in this instance.
		end
	end
	if switch == true then //switch to our new weapon if we should switch
		p.switchto = weapon
		p.switchslot = slot
		p.weaponstate = "Lower"
		p.weaponframe = 1
		p.frameduration = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe][3]
	end
	return slot, weapon //return slot and then weapon id
end

function RFW.PreviousWeapon(p, switch) //start switching to previous weapon
	if switch == nil then
		switch = true
	end
	local dick = 0
	local dick2 = 0
	local v = 0 //fucking stupid bullshit mhdfmmgfhmfgmhfgmhfmd.
	if p.switchto == nil or p.switchslot == nil then
		dick = p.weapon //store the weapon id
		dick2 = p.slot //and the slot, this saves performance and allows me to not have to write everything twice
	else //and thats because if we're already attempting to switch weapons
		dick = p.switchto //then we store the id of the weapon we're switching to!
		dick2 = p.switchslot //same with slot
	end
	local nextweapon = 0
	local weapon = 0
	local slot = dick2
	for k = #p.weaponslist[dick2], 1, -1 do //iterate through our current slot
		v = p.weaponslist[dick2][k] //theres no reverse ipairs so we hack one together like this
		if nextweapon == 1 then //if our next gun is the one we want then cache the weapon id
			weapon = v
			break
		end
		if v == dick then //if the current key value is our current gun
			nextweapon = 1
			continue
		end
	end
	if nextweapon == 1 and weapon == 0 then //if we need to find the next gun but we're out of guns in our current slot then iterate through the next slots
		for die = 1, 9 do //iterate through the next 9 slots
			local FUCK = dick2 - die //previous slot is our slot - 1
			if FUCK < 1 then //if we go below 1 than wrap back around
				FUCK = dick2 - die + 10
			end
			if #p.weaponslist[FUCK] ~= 0 then //if theres anything in this new slots table then logically it will always be the last weapon
				if #p.weaponslist[FUCK] == 1 then
					weapon = p.weaponslist[FUCK][1] //because indexing -1 to a table with a length of 1 returns nil ffs
				else
					weapon = p.weaponslist[FUCK][#p.weaponslist[FUCK]]
				end
				slot = FUCK
				break
			else
				continue
			end
		end
	end
	if nextweapon == 1 and weapon == 0 then //we STILL don't have a weapon! benson is gonna be so pissed bro.
		if #p.weaponslist[dick2] ~= 1 then //if we have more than one weapon in the slot
			local cache = #p.weaponslist[dick2] //index -1 doesnt work for some reason lul
			weapon = p.weaponslist[dick2][cache] //will always be the last weapon then, if we started from the last weapon of a slot and the length was more than 1 then we would have been done back at the first check
			slot = dick2 //it should still be dick2 anyways but we're just making sure
		else
			switch = false //we shouldn't try to switch to our same weapon again, never switch in this instance.
		end
	end
	if switch == true then //switch to our new weapon if we should switch
		p.switchto = weapon
		p.switchslot = slot
		p.weaponstate = "Lower"
		p.weaponframe = 1
		p.frameduration = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe][3]
	end
	return slot, weapon //return slot and then weapon id
end

function RFW.SlotWeapon(p, slot, switch) //start switching weapon based on slot
	if switch == nil then
		switch = true
	end
	local dick = 0
	local dick2 = 0
	local v = 0
	if p.switchto == nil or p.switchslot == nil then
		dick = p.weapon //store the weapon id
		dick2 = p.slot //and the slot, this saves performance and allows me to not have to write everything twice
	else //and thats because if we're already attempting to switch weapons
		dick = p.switchto //then we store the id of the weapon we're switching to!
		dick2 = p.switchslot //same with slot
	end
	local nextweapon = 0
	local weapon = 0
	if #p.weaponslist[slot] == 0 or (#p.weaponslist[slot] <= 1 and slot == dick2) then //if our slot is empty or the slot we're trying to switch to only has one weapon and we're already using/attempting to switch to that slot then stop
		return weapon, false
	end
	if dick2 == slot then //if the slot we're checking is the slot we already are using/attempting to switch to then we need to iterate to find the next weapon in the slot
		for k = #p.weaponslist[dick2], 1, -1 do //iterate through our current slot
			v = p.weaponslist[dick2][k] //theres no reverse ipairs so we hack one together like this
			if nextweapon == 1 then //if our next gun is the one we want then cache the weapon id
				weapon = v
				break
			end
			if v == dick then //if the current key value is our current gun
				nextweapon = 1
				continue
			end
		end
	end
	if weapon == 0 then //otherwise, if we're at the end of the slot or the slot we're switching to is different than the slot we're using/attempting to switch to then it should always be the first weapon of the slot.
		local en = #p.weaponslist[slot]
		weapon = p.weaponslist[slot][en] //first weapon of the slot, the weapon we have now should never be this already because of the first and second checks, never 1 sized table and always pick next weapon.
	end
	if switch == true then //switch to our new weapon if we should switch
		p.switchto = weapon
		p.switchslot = slot
		p.weaponstate = "Lower"
		p.weaponframe = 1
		p.frameduration = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe][3]
	end
	return weapon, true //return weapon id and true to indicate we switched successfully
end

function RFW.TrySelectWeapon(p, slot, constant)
	if not RFW.PlayerHasWeapon(p, slot, constant) then return false end //we don't have the weapon we want to switch to
	if not (p.weaponstate == "Ready" or p.weaponstate == "Lower" or p.weaponstate == "Raise") then return false end //we're not in a state that lets us switch
	if (p.weapon == constant) and (p.slot == slot) then return false end //we're already holding this weapon
	p.switchto = constant
	p.switchslot = slot
	p.weaponstate = "Lower"
	p.weaponframe = 1
	p.frameduration = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe][3]
end

function RFW.DoWeaponChange(p) //actually do the weapon change
	p.weapon = p.switchto //change weapon
	p.slot = p.switchslot //change slot
	p.weaponstate = "Raise" //always state to raise
	p.weaponframe = 1 //always first frame of raise state
	p.frameduration = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe][3] //set the duration of the raise state, for if you're a hippie
	p.flashstate = nil //we shouldn't be flashing
	p.flashframe = nil //no frame
	p.fframeduration = nil //no duration
	p.switchto = nil //we just switched, remove the switchto weapon
	p.switchslot = nil //same with slot
end

function RFW.WA_Refire(p)
	if p.weaponstate == "Fire" or p.weaponstate == "Hold" then
		if p.cmd.buttons & BT_ATTACK and RFW.WA_AmmoCheck(p, RFW.Weapons[p.slot][p.weapon]["AmmoType"], RFW.Weapons[p.slot][p.weapon]["MinAmmo"]) then
			p.weaponstate = RFW.Weapons[p.slot][p.weapon]["States"]["Hold"] and "Hold" or "Fire"
			p.weaponframe = 1
			p.frameduration = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe][3]
			p.refire = true
			local yourweapon = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe]
			if yourweapon and yourweapon.action then
				yourweapon.action(p, yourweapon.arg1 or nil, yourweapon.arg2 or nil, yourweapon.arg3 or nil, yourweapon.arg4 or nil, yourweapon.arg5 or nil, yourweapon.arg6 or nil, yourweapon.arg7 or nil, yourweapon.arg8 or nil, yourweapon.arg9 or nil)
			end
		end
	elseif p.weaponstate == "AltFire" or p.weaponstate == "AltHold" then
		if p.cmd.buttons & BT_FIRENORMAL and RFW.WA_AmmoCheck(p, RFW.Weapons[p.slot][p.weapon]["AmmoType"], RFW.Weapons[p.slot][p.weapon]["MinAmmo"]) then
			p.weaponstate = RFW.Weapons[p.slot][p.weapon]["States"]["AltHold"] and "AltHold" or "AltFire"
			p.weaponframe = 1
			p.frameduration = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe][3]
			p.refire = true
			local yourweapon = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe]
			if yourweapon and yourweapon.action then
				yourweapon.action(p, yourweapon.arg1 or nil, yourweapon.arg2 or nil, yourweapon.arg3 or nil, yourweapon.arg4 or nil, yourweapon.arg5 or nil, yourweapon.arg6 or nil, yourweapon.arg7 or nil, yourweapon.arg8 or nil, yourweapon.arg9 or nil)
			end
		end
	else
		if p.cmd.buttons & BT_ATTACK and RFW.WA_AmmoCheck(p, RFW.Weapons[p.slot][p.weapon]["AmmoType"], RFW.Weapons[p.slot][p.weapon]["MinAmmo"]) then //fix this to check if states exist
			p.weaponstate = "Fire"
			p.weaponframe = 1
			p.frameduration = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe][3]
			p.refire = true
			local yourweapon = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe]
			if yourweapon and yourweapon.action then
				yourweapon.action(p, yourweapon.arg1 or nil, yourweapon.arg2 or nil, yourweapon.arg3 or nil, yourweapon.arg4 or nil, yourweapon.arg5 or nil, yourweapon.arg6 or nil, yourweapon.arg7 or nil, yourweapon.arg8 or nil, yourweapon.arg9 or nil)
			end
		end
		if p.cmd.buttons & BT_FIRENORMAL and RFW.WA_AmmoCheck(p, RFW.Weapons[p.slot][p.weapon]["AmmoType"], RFW.Weapons[p.slot][p.weapon]["MinAmmo"]) then //fix this to check if states exist
			p.weaponstate = RFW.Weapons[p.slot][p.weapon]["States"]["AltFire"] and "AltFire" or "Fire" //check that our altfire state exists
			p.weaponframe = 1
			p.frameduration = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe][3]
			p.refire = true
			local yourweapon = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe]
			if yourweapon and yourweapon.action then
				yourweapon.action(p, yourweapon.arg1 or nil, yourweapon.arg2 or nil, yourweapon.arg3 or nil, yourweapon.arg4 or nil, yourweapon.arg5 or nil, yourweapon.arg6 or nil, yourweapon.arg7 or nil, yourweapon.arg8 or nil, yourweapon.arg9 or nil)
			end
		end
	end
end

function RFW.WA_AmmoCheck(p, id, amount)
	if id == 0 then return true end //ammoless weapon id
	if not RFW.Ammoids[id] then return false end
	if not p.ammolist[id] then return false end
	if p.ammolist[id] < amount then return false end
	return true
end

function RFW.WA_UseAmmo(p, fire, amount) //fire: 0 = ammo, 1 = ammo1, 2 = ammo2.
	if fire == nil then
		fire = 0
	end
	if amount == nil then
		amount = 1
	end
	local atype = (fire == 1) and "AmmoType1" or (fire == 2) and "AmmoType2" or "AmmoType"
	local ammoid = RFW.Weapons[p.slot][p.weapon][atype]
	//if RFW.WA_AmmoCheck(p, ammoid, RFW.Weapons[p.slot][p.weapon]["MinAmmo"]) //not needed because ammo checker at start of firing, if you need to check other ammo types then do them manually
	p.ammolist[ammoid] = max($ - amount, 0)
end

/*local fucknipple = CV_RegisterVar({
	name = "cummy",
	defaultvalue = 17,
	PossibleValue = {MIN = 0, MAX = 200},
	flags = CV_NETVAR,
})*/

/*function RFW.StupidZBullshit(p) //because srb2 FUCKING SUCKS GRAHH
	if P_MobjFlip(p.mo) == 1 then
		return p.mo.z+(p.mo.height*3/4)
	elseif P_MobjFlip(p.mo) == -1 then
		return p.mo.z+(p.mo.height*17/200) //"why 17/200 rdude??" i have no fucking idea. Its still not even technically fully accurate, just much closer.
	else
		return 0
	end
end

function RFW.Sound(p, radius)
	searchBlockmap("objects", function(ref, object)
		if not (object.flags|MF_ENEMY|MF_BOSS) then return nil end
		if (object.target and object.target.valid) then return nil end
		object.target = ref
	end, p.mo, p.mo.x-radius, p.mo.x+radius, p.mo.y-radius, p.mo.y+radius)
end

function RFW.WA_BasicHitscan(p, damage, angle, aim, range, step)
	//aim assist start
	local mangle = 0 //set these to zero, if we dont have bullet magnetism then we add 0 to our angle
	local maim = 0 //else if we do these'll be added to our angle to aim towards our target
	if p.aimassist and p.bulletmagnetism and p.mo.lockontarget then
		if RFW.vertassist.value ~= 1 then
			mangle = R_PointToAngle2(p.mo.x, p.mo.y, p.mo.lockontarget.x, p.mo.lockontarget.y)
		end
		local vector = R_PointToDist2(p.mo.x, p.mo.y, p.mo.lockontarget.x, p.mo.lockontarget.y)
		maim = R_PointToAngle2(0, p.mo.z+p.mo.height/2, vector, p.mo.lockontarget.z+p.mo.lockontarget.height/2)
		if RFW.vertassist.value ~= 1 then
			mangle = $ - p.mo.angle //change these to delta so we can add them to our current value
		end
		maim = $ - p.aiming
	end
	//aim assist end
	local targetlist = P_AngleRaycast{x = p.mo.x, y = p.mo.y, z = RFW.StupidZBullshit(p), ang = (angle or p.mo.angle) + mangle, zang = (aim or p.aiming) + maim, distance = range or 4096*FU, steps = step or 256, tclip = true, lclip = true, ignore = p.mo, callback2 = P_SpawnMobj, larg = MT_SMOKE}
	if not next(targetlist) then return false end
	local target = targetlist[1][4]
	if target.type == MT_PLAYER then
		if CanPlayerHurtPlayer(p, target.player, 1, 0) == true then
			Playerdamage(target, p.mo, p.mo, damage or 5, 0, true)
			return true
		end
	else
		for i = 1, P_RandomRange(1, 3) do
			RFW.SparkCoordinate(target, targetlist[1][1], targetlist[1][2], targetlist[1][3])
		end
		P_DamageMobj(target, p.mo, p.mo, damage or 5, 0)
		return true
	end
end

function RFW.WA_Flash(p)
	if RFW.Weapons[p.slot][p.weapon]["States"]["Flash"] then
		p.flashstate = "Flash"
		p.flashframe = 1
		p.fframeduration = RFW.Weapons[p.slot][p.weapon]["States"][p.flashstate][p.flashframe][3]
		//P_FlashPal(p, 8, p.fframeduration)
		return true
	end
	return false
end

function RFW.WA_LightningHitscan(p, damage, angle, aim, range, step)
	local mangle = 0 //set these to zero, if we dont have bullet magnetism then we add 0 to our angle
	local maim = 0 //else if we do these'll be added to our angle to aim towards our target
	if p.aimassist and p.bulletmagnetism and p.mo.lockontarget then
		if RFW.vertassist.value ~= 1 then
			mangle = R_PointToAngle2(p.mo.x, p.mo.y, p.mo.lockontarget.x, p.mo.lockontarget.y)
		end
		local vector = R_PointToDist2(p.mo.x, p.mo.y, p.mo.lockontarget.x, p.mo.lockontarget.y)
		maim = R_PointToAngle2(0, p.mo.z+p.mo.height/2, vector, p.mo.lockontarget.z+p.mo.lockontarget.height/2)
		if RFW.vertassist.value ~= 1 then
			mangle = $ - p.mo.angle //change these to delta so we can add them to our current value
		end
		maim = $ - p.aiming
	end
	local targetlist = P_AngleRaycast{x = p.mo.x, y = p.mo.y, z = RFW.StupidZBullshit(p), ang = (angle or p.mo.angle) + mangle, zang = (aim or p.aiming) + maim, distance = range or 4096*FU, steps = step or 256, tclip = false, lclip = true, ignore = p.mo, callback = P_SpawnMobj, arg = MT_LIGHTNING}
	if not next(targetlist) then return false end
	for i = 1, #targetlist do
		local target = targetlist[i][4]
		if target.type == MT_PLAYER then
			if CanPlayerHurtPlayer(p, target.player, 1, 0) == true then
				Playerdamage(target, p.mo, p.mo, damage or 5, 0, true)
			end
		else
			P_DamageMobj(target, p.mo, p.mo, damage or 5, 0)
		end
	end
end

function RFW.WA_SniperHitscan(p, damage, angle, aim, range, step)
	local mangle = 0 //only do horizontal aiming so that headshots can still be hit
	if p.aimassist and p.bulletmagnetism and p.mo.lockontarget and RFW.vertassist.value ~= 1 then
		mangle = R_PointToAngle2(p.mo.x, p.mo.y, p.mo.lockontarget.x, p.mo.lockontarget.y)
		mangle = $ - p.mo.angle //change these to delta so we can add them to our current value
	end
	local targetlist = P_AngleRaycast{x = p.mo.x, y = p.mo.y, z = RFW.StupidZBullshit(p), ang = (angle or p.mo.angle) + mangle, zang = aim or p.aiming, distance = range or 4096*FU, steps = step or 256, tclip = false, lclip = true, ignore = p.mo, callback = P_SpawnMobj, arg = MT_SMOKE}
	if not next(targetlist) then return false end
	for i = 1, #targetlist do
		//local headshotheight = targetlist[i][4].type // later
		local target = targetlist[i][4]
		if target.type == MT_PLAYER then
			if CanPlayerHurtPlayer(p, target.player, 1, 0) == true then
				if targetlist[i][3] >= targetlist[i][4].z + targetlist[i][4].height/2 and targetlist[i][3] <= targetlist[i][4].z + targetlist[i][4].height then
					damage = 200
				end
				Playerdamage(target, p.mo, p.mo, damage or 5, 0, true)
			end
		else
			P_DamageMobj(target, p.mo, p.mo, damage or 5, 0)
		end
	end
end

/*function RFW.WA_RailHitscan(p, damage, angle, aim, range, step)
	//maybe lets not bullet magnetize this one lol
	local targetlist = P_AngleRaycast{x = p.mo.x, y = p.mo.y, z = RFW.StupidZBullshit(p), ang = angle or p.mo.angle, zang = aim or p.aiming, distance = range or 4096*FU, steps = step or 256, tclip = false, lclip = true, ignore = p.mo, callback = RFW.SpawnRailtrail, arg = p}
	if not next(targetlist) then return false end
	for i = 1, #targetlist do
		local target = targetlist[i][4]
		if target.type == MT_PLAYER then
			if CanPlayerHurtPlayer(p, target.player, 1, 0) == true then
				Playerdamage(target, p.mo, p.mo, damage or 5, 0, true)
			end
		else
			P_DamageMobj(target, p.mo, p.mo, damage or 5, 0)
		end
	end
end*/

/*function RFW.WA_RailHitscan(p, damage, edamage, angle, aim, range, step)
	//maybe lets not bullet magnetize this one lol
	local targetlist = P_AngleRaycast{x = p.mo.x, y = p.mo.y, z = RFW.StupidZBullshit(p), ang = angle or p.mo.angle, zang = aim or p.aiming, distance = range or 4096*FU, steps = step or 256, tclip = false, lclip = true, ignore = p.mo, callback = RFW.SpawnRailtrail, arg = p}
	if not next(targetlist) then return false end
	for i = 1, #targetlist do
		local target = targetlist[i][4]
		if target.type == MT_PLAYER then
			if CanPlayerHurtPlayer(p, target.player, 1, 0) == true then
				Playerdamage(target, p.mo, p.mo, damage or 5, 0, true)
			end
		else
			local hx = targetlist[1][1]
			local hy = targetlist[1][2]
			local hz = targetlist[1][3]
			for i = 1, P_RandomRange(20, 30) do
				RFW.SparkCoordinate(target, hx, hy, hz)
			end
			for i = 1, P_RandomRange(10, 15) do
				RFW.Bleed(target)
			end
			P_DamageMobj(target, p.mo, p.mo, edamage or 5, 0)
		end
	end
end

function RFW.WA_PistolShot(p)
	local angle1 = 0
	local angle2 = 0
	if p.refire then
		angle1 = FixedAngle(P_RandomRange(-FU, FU))
		angle2 = FixedAngle(P_RandomRange(-FU, FU))
	end
	RFW.WA_Flash(p)
	RFW.WA_UseAmmo(p)
	RFW.WA_BasicHitscan(p, P_RandomRange(20, 25), p.mo.angle + angle1, p.aiming + angle2, 4096*FU, 1024)
	S_StartSound(p.mo, sfx_PISTOL)
end

function RFW.WA_SGShot(p)
	RFW.WA_Flash(p)
	RFW.WA_UseAmmo(p)
	for i = 1, 7 do
		RFW.WA_BasicHitscan(p, P_RandomRange(12, 15), p.mo.angle + FixedAngle(P_RandomRange(-3*FU/2, 3*FU/2)), p.aiming + FixedAngle(P_RandomRange(-FU, FU)), 4096*FU, 256)
	end
	S_StartSound(p.mo, sfx_SHOTFR)
end

function RFW.WA_SGRel(p)
	S_StartSound(p.mo, sfx_SHOTPM)
end

function RFW.WA_ChaingunShot(p)
	local angle1 = 0
	local angle2 = 0
	if p.refire then
		angle1 = FixedAngle(P_RandomRange(-2*FU, 2*FU))
		angle2 = FixedAngle(P_RandomRange(-FU, FU))
	end
	RFW.WA_UseAmmo(p)
	//old damage P_RandomRange(5, 15)
	RFW.WA_BasicHitscan(p, P_RandomRange(12, 15), p.mo.angle + angle1, p.aiming + angle2, 8192*FU, 2048)
	S_StartSound(p.mo, sfx_CHAING)
end

function RFW.WA_GrenadeOpen(p)
	S_StartSound(p.mo, sfx_GROPEN)
end

function RFW.WA_GrenadeLoad(p)
	S_StartSound(p.mo, sfx_GRLOAD)
end

function RFW.WA_GrenadeClose(p)
	S_StartSound(p.mo, sfx_GRCLOS)
end

function RFW.WA_GrenadeShot(p)
	RFW.WA_UseAmmo(p)
	local FUCK = P_SPMAngle(p.mo, MT_SHOTGRENADE, p.mo.angle, 1)
	S_StartSound(p.mo, sfx_cannon)
	P_SetObjectMomZ(FUCK, 6*FU*P_MobjFlip(p.mo), true)
end

function RFW.WA_RocketShot(p)
	RFW.WA_UseAmmo(p)
	P_SPMAngle(p.mo, MT_RMPROCKET, p.mo.angle, 1)
	S_StartSound(p.mo, sfx_cannon)
end

function RFW.WA_RifleAutoShot(p)
	local angle1 = 0
	local angle2 = 0
	if p.refire then
		angle1 = FixedAngle(P_RandomRange(-2*FU, 2*FU))
		angle2 = FixedAngle(P_RandomRange(-2*FU, 2*FU))
	end
	RFW.WA_UseAmmo(p)
	RFW.WA_BasicHitscan(p, P_RandomRange(15, 20), p.mo.angle + angle1, p.aiming + angle2, 4096*FU, 1024)
	S_StartSound(p.mo, sfx_THOMFR)
	p.refire = true
end

function RFW.WA_KarasawaShot(p)
	RFW.WA_Flash(p)
	RFW.WA_UseAmmo(p)
	local bolt = P_SPMAngle(p.mo, MT_KARABOLT, p.mo.angle, 1)
	bolt.color = p.secondcolor
	S_StartSound(p.mo, sfx_KARAFR)
end

function RFW.WA_KarasawaFlash(p)
	S_StartSound(p.mo, sfx_KARAID)
	/*if RFW.Weapons[p.slot][p.weapon]["States"]["KFlash"] then
		p.flashstate = "KFlash"
		p.flashframe = 1
		p.fframeduration = RFW.Weapons[p.slot][p.weapon]["States"][p.flashstate][p.flashframe][3]
		//P_FlashPal(p, 8, p.fframeduration)
		return true
	end
	return false*/
/*end

function RFW.WA_RailFire(p)
	RFW.WA_UseAmmo(p, 0, 10)
	RFW.WA_RailHitscan(p, 100, 150, p.mo.angle, p.aiming, 8192*FU, 2048)
	S_StartSound(p.mo, sfx_RAILFR)
end

function RFW.WA_RailCharge(p)
	S_StartSound(p.mo, sfx_RAILCH)
end

function RFW.WA_SniperFire(p)
	RFW.WA_UseAmmo(p)
	RFW.WA_SniperHitscan(p, 75, p.mo.angle, p.aiming, 8192*FU, 2048)
	S_StartSound(p.mo, sfx_SNIPE1)
end

function RFW.WA_SniperBolt1(p)
	S_StartSound(p.mo, sfx_SNIPE2)
end

function RFW.WA_SniperBolt2(p)
	S_StartSound(p.mo, sfx_SNIPE3)
end

function RFW.WA_LightningShot(p)
	if p.mo.eflags & MFE_UNDERWATER then
		RFW.WA_Flash(p)
		RFW.WA_UseAmmo(p)
		Playerdamage(p.mo, nil, nil, 99999, 0, true)
		S_StartSound(p.mo, sfx_Q3BOOM)
		return false
	end
	RFW.WA_Flash(p)
	RFW.WA_UseAmmo(p)
	RFW.WA_LightningHitscan(p, 6, p.mo.angle, p.aiming, 512*FU, 32)
	S_StartSound(p.mo, sfx_LIGHTN)
end

function RFW.WA_LightningShot2(p)
	if p.mo.eflags & MFE_UNDERWATER then
		Playerdamage(p.mo, nil, nil, 99999, 0, true)
		S_StartSound(p.mo, sfx_Q3BOOM)
		return false
	end
	RFW.WA_LightningHitscan(p, 6, p.mo.angle, p.aiming, 512*FU, 32)
end

function RFW.WA_AxeLunge(p)
	local targetlist = P_AngleRaycast{x = p.mo.x, y = p.mo.y, z = RFW.StupidZBullshit(p), ang = angle or p.mo.angle, zang = aim or p.aiming, distance = 512*FU, steps = 32, tclip = true, lclip = true, ignore = p.mo}
	if not next(targetlist) then return false end //somebody within 512FU
	local target = targetlist[1][4] //we're about to replace target list so save this variable
	local targetlist = P_AngleRaycast{x = p.mo.x, y = p.mo.y, z = RFW.StupidZBullshit(p), ang = angle or p.mo.angle, zang = aim or p.aiming, distance = 128*FU, steps = 32, tclip = true, lclip = true, ignore = p.mo}
	if next(targetlist) then return false end //and farther than 128FU
	local distance = R_PointToDist2(p.mo.x, p.mo.y, target.x, target.y)
	local thrust = (distance-128*FU)/4 //3 tics to hit so 3 tic buffer
	p.mo.z = $ + FU*P_MobjFlip(p.mo) //lift off ground by 1FU to prevent dragging on the ground
	P_Thrust(p.mo, p.mo.angle, FixedMul(thrust, cos(p.aiming)))
	p.mo.momz = $ + FixedMul(thrust, sin(p.aiming)) //* P_MobjFlip(p.mo)
end

function RFW.WA_AxeHitscan(p, damage, angle, aim, range, step)
	local targetlist = P_AngleRaycast{x = p.mo.x, y = p.mo.y, z = RFW.StupidZBullshit(p), ang = angle or p.mo.angle, zang = aim or p.aiming, distance = range or 4096*FU, steps = step or 256, tclip = true, lclip = true, ignore = p.mo, callback2 = P_SpawnMobj, larg = MT_SMOKE, sarg = MT_FLAMEPARTICLE}
	if not next(targetlist) then return false end
	local target = targetlist[1][4]
	if target.type == MT_PLAYER then
		damage = 100
		if CanPlayerHurtPlayer(p, target.player, 1, 0) == true then
			Playerdamage(target, p.mo, p.mo, damage or 5, 0, true)
			return true
		end
	else
		damage = 25
		P_DamageMobj(target, p.mo, p.mo, damage or 5, 0)
		return true
	end
end

function RFW.WA_AxeIdle(p)
	S_StartSound(p.mo, sfx_ENRGID)
end

function RFW.WA_AxeHit(p)
	S_StartSound(p.mo, sfx_ENRGFR)
	RFW.WA_AxeHitscan(p, 100, p.mo.angle, p.aiming, 128*FU, 32)
end

function RFW.WA_SniperScope(p)
	p.fovadd = -45*FU
end

function RFW.WA_ScopeRefire(p)
	p.fovadd = -45*FU
	RFW.WA_Refire(p)
end

function RFW.WA_Lower(p)
	p.raiselowercounter = max(min($ + 6, 32), 0)
end

function RFW.WA_Raise(p)
	p.raiselowercounter = max(min($ - 6, 32), 0)
end

function RFW.WA_AxeRaise1(p)
	p.raiselowercounter = 1
end

function RFW.WA_AxeRaise2(p)
	p.raiselowercounter = 0
end

addHook("PlayerSpawn", function(p)
	if not (gametyperules & GTR_CAMPAIGN) then
		p.initialized = false
	end
end)

addHook("PlayerThink", function(p)
	p.weapondelay = 9
	if p.spectator or p.playerstate == PST_DEAD then
		p.slot = nil
		p.weapon = nil
		p.raiselowercounter = 0
		p.weaponframe = nil
		p.frameduration = nil
		p.flashstate = nil
		p.flashframe = nil
		p.fframeduration = nil
		p.switchto = nil
		p.switchslot = nil
		p.refire = false
		p.initialized = false
		p.weaponslist = {
			[1] = {},
			[2] = {},
			[3] = {},
			[4] = {},
			[5] = {},
			[6] = {},
			[7] = {},
			[8] = {},
			[9] = {},
			[10] = {},
		}
		p.ammolist = {
			[1] = 50,
			[2] = 0,
			[3] = 0,
			[4] = 0,
		}
	end
	if p.raiselowercounter == nil then
		p.raiselowercounter = 0
	end
	if p.raiselowercounter > 32 then
		p.raiselowercounter = 32
	end
	if p.raiselowercounter >= 32 and p.switchto ~= nil then
		RFW.DoWeaponChange(p)
	end
	if p.raiselowercounter <= 0 then
		p.raiselowercounter = 0
		if p.weaponstate == "Raise" then
			p.weaponstate = "Ready"
		end
	end
//
	if p.playerstate == PST_DEAD then
		p.weaponstate = "Ready"
		p.weaponframe = 1
		p.frameduration = 2
		p.flashstate = nil
		p.flashframe = nil
		p.fframeduration = nil
		p.switchto = nil
		p.switchslot = nil
		p.refire = false
		p.weaponslist = {
			[1] = {},
			[2] = {},
			[3] = {},
			[4] = {},
			[5] = {},
			[6] = {},
			[7] = {},
			[8] = {},
			[9] = {},
			[10] = {},
		}
		p.ammolist = {
			[1] = 50,
			[2] = 0,
			[3] = 0,
			[4] = 0,
		}
	end
	if p.cmd.buttons & BT_WEAPONNEXT and not (p.lastbuttons & BT_WEAPONNEXT) and (p.weaponstate == "Ready" or p.weaponstate == "Lower" or p.weaponstate == "Raise") then
		RFW.NextWeapon(p)
	end
	if p.cmd.buttons & BT_WEAPONPREV and not (p.lastbuttons & BT_WEAPONPREV) and (p.weaponstate == "Ready" or p.weaponstate == "Lower" or p.weaponstate == "Raise") then
		RFW.PreviousWeapon(p)
	end
//
	if p.cmd.buttons & BT_WEAPONMASK and not (p.lastbuttons & BT_WEAPONMASK) and (p.weaponstate == "Ready" or p.weaponstate == "Lower" or p.weaponstate == "Raise") then
		RFW.SlotWeapon(p, (p.cmd.buttons & BT_WEAPONMASK))
	end
//
	if not p.initialized and not p.spectator then
		p.weaponslist = {
			[1] = {},
			[2] = {},
			[3] = {},
			[4] = {},
			[5] = {},
			[6] = {},
			[7] = {},
			[8] = {},
			[9] = {},
			[10] = {},
		}
		RFW.GivePlayerWeapon(p, 1, RFW.WP_pistol)
		RFW.GivePlayerWeapon(p, 1, RFW.WP_axe)
		p.weaponstate = "Raise"
		p.slot = 1
		p.weapon = RFW.WP_pistol
		p.raiselowercounter = 32
		p.weaponframe = 1
		p.frameduration = 2
		p.flashstate = nil
		p.flashframe = nil
		p.fframeduration = nil
		p.switchto = nil
		p.switchslot = nil
		p.ammolist = {
		[1] = 50,
		[2] = 0,
		[3] = 0,
		[4] = 0,
		}
		p.refire = false
		p.initialized = true
	end
	if RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate] and RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe].zoom then
		local zoom = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe].zoom
		p.fovadd = -zoom*FU
	end
	if p.frameduration > 0 then
		p.frameduration = $ - 1
	end
	if p.fframeduration and p.fframeduration > 0 then
		p.fframeduration = $ - 1
	end
	if p.fframeduration == 0 then
		p.flashframe = $ + 1
		local yourflash = RFW.Weapons[p.slot][p.weapon]["States"][p.flashstate][p.flashframe]
		if not yourflash then
			p.flashstate = nil
			p.flashframe = nil
			p.fframeduration = nil
		elseif yourflash[1] == "Loop" then
			print("Do not call attempt to call loop in a flash state! Exitting flash now:")
			p.flashstate = nil
			p.flashframe = 0
			p.fframeduration = 0
		elseif yourflash[1] == "Goto" then
			p.flashstate = yourflash[2] or "Flash"
			p.flashframe = 1
			p.fframeduration = RFW.Weapons[p.slot][p.weapon]["States"][p.flashstate][p.flashframe][3]
		else
			p.fframeduration = RFW.Weapons[p.slot][p.weapon]["States"][p.flashstate][p.flashframe][3]
		end
		local yourweapon = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe]
		if yourweapon and yourweapon.action then
			yourweapon.action(p, yourweapon.arg1 or nil, yourweapon.arg2 or nil, yourweapon.arg3 or nil, yourweapon.arg4 or nil, yourweapon.arg5 or nil, yourweapon.arg6 or nil, yourweapon.arg7 or nil, yourweapon.arg8 or nil, yourweapon.arg9 or nil)
		end
	end
	if p.weaponstate == "Ready" and p.refire == true then
		p.refire = false
	end
	if p.cmd.buttons & BT_ATTACK and p.weaponstate == "Ready" and RFW.WeaponValid(p) then
		if RFW.WA_AmmoCheck(p, RFW.Weapons[p.slot][p.weapon]["AmmoType"], RFW.Weapons[p.slot][p.weapon]["MinAmmo"]) and p.playerstate ~= PST_DEAD then
			p.weaponstate = "Fire"
			p.weaponframe = 1
			p.frameduration = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe][3]
			local yourweapon = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe]
			if yourweapon and yourweapon.action then
				yourweapon.action(p, yourweapon.arg1 or nil, yourweapon.arg2 or nil, yourweapon.arg3 or nil, yourweapon.arg4 or nil, yourweapon.arg5 or nil, yourweapon.arg6 or nil, yourweapon.arg7 or nil, yourweapon.arg8 or nil, yourweapon.arg9 or nil)
			end
		else
			RFW.NextWeapon(p, true)
		end
	end
	if p.cmd.buttons & BT_FIRENORMAL and p.weaponstate == "Ready" and RFW.WeaponValid(p) then
		if RFW.WA_AmmoCheck(p, RFW.Weapons[p.slot][p.weapon]["AmmoType"], RFW.Weapons[p.slot][p.weapon]["MinAmmo"]) and p.playerstate ~= PST_DEAD then
			p.weaponstate = RFW.Weapons[p.slot][p.weapon]["States"]["AltFire"] and "AltFire" or "Fire"
			p.weaponframe = 1
			p.frameduration = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe][3]
			local yourweapon = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe]
			if yourweapon and yourweapon.action then
				yourweapon.action(p, yourweapon.arg1 or nil, yourweapon.arg2 or nil, yourweapon.arg3 or nil, yourweapon.arg4 or nil, yourweapon.arg5 or nil, yourweapon.arg6 or nil, yourweapon.arg7 or nil, yourweapon.arg8 or nil, yourweapon.arg9 or nil)
			end
		else
			RFW.NextWeapon(p, true)
		end
	end
	if p.frameduration == 0 then
		for i = 1,256 do //256 max skip frames, after 256 frames emergency exit as we might be caught in a loop.
			p.weaponframe = $ + 1
			local yourweapon = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe]
			if not yourweapon then
				print("FUCKING IDIOT DEVELOPER! USE LOOP OR GOTO TO END WEAPON STATES! (flashes excluded)")
				p.weaponstate = "Ready"
				p.weaponframe = 1
				p.frameduration = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe][3]
			elseif yourweapon[1] == "Loop" then
				p.weaponframe = 1
				p.frameduration = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe][3]
			elseif yourweapon[1] == "Goto" then
				p.weaponstate = yourweapon[2] or "Ready"
				p.weaponframe = 1
				p.frameduration = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe][3]
			else
				p.frameduration = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe][3]
			end
			local yourweapon = RFW.Weapons[p.slot][p.weapon]["States"][p.weaponstate][p.weaponframe]
			if yourweapon and yourweapon.action then
				yourweapon.action(p, yourweapon.arg1 or nil, yourweapon.arg2 or nil, yourweapon.arg3 or nil, yourweapon.arg4 or nil, yourweapon.arg5 or nil, yourweapon.arg6 or nil, yourweapon.arg7 or nil, yourweapon.arg8 or nil, yourweapon.arg9 or nil)
			end
			if p.frameduration > 0 then
				break //stop skipping!!
			else
				continue //frame is 0 tics long, skippppp
			end
		end
	end
end)	

hud.add(function(v, p, c)
	local bcenterx = 160 - ((v.width()/(v.dupx() * 2) - 160))
	local bcentery = 100 + ((v.height()/(v.dupy() * 2) - 100))
	if p.spectator then return end
	local currentweapon = RFW.Weapons[p.slot][p.weapon]
	if ((p ~= secondarydisplayplayer and not camera.chase) or (p == secondarydisplayplayer and not camera2.chase)) and (not (p.mapopen and (not p.overlaymap))) and p.pstate ~= PST_DEAD then
		local bobxoffset = 0
		local bobyoffset = 0
//		local currentweapon = RFW.Weapons[p.slot][p.weapon]
		local weapframe = currentweapon["States"][p.weaponstate][p.weaponframe]
		local flashframe = nil
		if p.flashstate and p.flashframe then
			flashframe = currentweapon["States"][p.flashstate][p.flashframe] or nil
		end
		if p.weaponstate == "Ready" then
			if RFW.bobstyle == 1 then
				bobxoffset = FixedInt(FixedMul(p.bob, sin(FixedAngle(leveltime*16*FU))))
				bobyoffset = FixedInt(FixedMul(p.bob/2, abs(sin(FixedAngle(leveltime*16*FU)))))
			elseif RFW.bobstyle == 2 then
				bobxoffset = FixedInt(2*sin(FixedAngle(leveltime*2*FU)))
				bobyoffset = FixedInt(FixedMul(p.bob/2, sin(FixedAngle(leveltime*16*FU))))
			else
				bobxoffset = 0
				bobyoffset = 0
			end
		end
		v.draw(bcenterx-bobxoffset, 200-bobyoffset+(p.raiselowercounter), v.cachePatch(weapframe[1] .. weapframe[2] .. 0), (weapframe.renderflags) and weapframe.renderflags|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_PERPLAYER or (V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_PERPLAYER), v.getSectorColormap(p.mo.subsector.sector, p.mo.x, p.mo.y, p.mo.z+(p.mo.height/2), P_GetSectorLightLevelAt(p.mo.subsector.sector, p.mo.x, p.mo.y, p.mo.z+(p.mo.height/2))))//v.getSectorColormap(p.realmo.subsector.sector, p.realmo.x, p.realmo.y, p.realmo.z+(p.realmo.height/2))
		//brightmap rendering
		if weapframe.brightmap then
			v.draw(bcenterx-bobxoffset, 200-bobyoffset+(p.raiselowercounter), v.cachePatch(weapframe.brightmap .. weapframe.brightframe .. 0), (weapframe.brightflags) and weapframe.brightflags|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_PERPLAYER or (V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_PERPLAYER), v.getColormap(TC_DEFAULT))
		end
		//colormap rendering
		if weapframe.colormap then
			v.draw(bcenterx-bobxoffset, 200-bobyoffset+(p.raiselowercounter), v.cachePatch(weapframe.colormap .. weapframe.colorframe .. 0), (weapframe.colorflags) and weapframe.colorflags|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_PERPLAYER or (V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_PERPLAYER), v.getColormap(TC_DEFAULT, p.secondcolor))
		end
		//weapon flash rendering
		if flashframe then
			v.draw(bcenterx-bobxoffset, 200-bobyoffset+(p.raiselowercounter), v.cachePatch(flashframe[1] .. flashframe[2] .. 0), (flashframe.renderflags) and flashframe.renderflags|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_PERPLAYER or (V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_PERPLAYER|V_ADD), v.getColormap(TC_DEFAULT))
		end
	end
	local ammotype = RFW.Weapons[p.slot][p.weapon]["AmmoType"]
	if ammotype ~= 0 then
		v.drawString(bcenterx, 160, tostring(p.ammolist[ammotype]), V_ALLOWLOWERCASE|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_PERPLAYER, "center")
	end
	if p.weaponstate == "Lower" then
		//local weaponname = ((p.switchslot and p.switchto) and (RFW.Weapons[p.switchslot][p.switchto]["Name"] or "Unidentified Weapon"))
		v.drawString(bcenterx, 168, tostring(RFW.Weapons[p.switchslot][p.switchto]["WeaponName"] or "Unidentified Weapon"), V_ALLOWLOWERCASE|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_PERPLAYER|V_50TRANS|V_YELLOWMAP, "small-center")
	elseif p.weaponstate == "Raise" then
		v.drawString(bcenterx, 168, tostring(currentweapon["WeaponName"] or "Unidentified Weapon"), V_ALLOWLOWERCASE|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_PERPLAYER|V_50TRANS|V_YELLOWMAP, "small-center")
	end
	if p.weaponstate ~= "Lower" and p.weaponstate ~= "Raise" and c.chase then
		v.drawString(bcenterx, 168, tostring(currentweapon["WeaponName"] or "Unidentified Weapon"), V_ALLOWLOWERCASE|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_PERPLAYER|V_20TRANS, "small-center")
	end
end)

/*RFW.SelectWeapon(p, switch)

function RFW.NextWeapon(p, switch)
	local nextweapon = false
	local weaponchose = nil
	for k, v in pairs(p.weaponslist) do
		if nextweapon == true then
			if switch == true then
			RFW
		elseif p.weaponslist[k] == p.currentweapon then
			nextweapon == true
		end
	end
	return
end

function RFW.PrevWeapon(p, switch)
	local nextweapon = false
	
end

function RFW.SlotWeapon(p, switch)
	local nextweapon = false
	
end*/

/*{
	["WeaponName"] = "Handgun",
	["AmmoType"] = 1,
	["AmmoType1"] = 1,
	["AmmoType2"] = 1,
	["MinAmmo"] = 1,
		["States"] = {
			["Ready"] = {
				{PISG, A, 1},
				{Loop}
			},
			
			["Lower"] = {
				{PISG, A, 1, WA_Lower},
				{Loop}
			},
			
			["Raise"] = {
				{PISG, A, 1, WA_Raise},
				{Loop}
			},
			
			["Fire"] = {
				{PISG, B, 3, WA_PistolShot},
				{PISG, C, 2},
				{PISG, D, 2},
				{PISG, E, 2},
				{PISG, D, 1},
				{PISG, C, 1},
				{PISG, B, 1, WA_Refire},
				{Goto, "Ready"}
			},
			
			["Flash"] = { //for easier weapon porting from stuff like zdoom mods, completely optional if not calling the flash state.
				{PISF, A, 3}
				{Stop}
			},
			
			["AltFire"] = {
			},
			
			["AltFlash"] = {
			},
			
			["Hold"] = {
			},
			
			["AltHold"] = {
			},
		}
	}*/